import io
import pathlib
from urllib.parse import quote
from uuid import UUID

import openpyxl
from fastapi import APIRouter, Depends
from fastapi.exceptions import HTTPException
from fastapi.responses import StreamingResponse

from core.database import get_db
from service.summary_service import SummaryService
from schema.all import POSTResponse

router = APIRouter()


@router.post(path="/sea", response_model=POSTResponse)
async def create_sea_summary(
    tender_id: UUID,
    db=Depends(get_db),
):
    service = SummaryService(db)
    summary_file = await service.create_summary(tender_id)
    return POSTResponse(message=f"汇总成功，文件名：{summary_file.name}")


@router.get(path="/sea", response_class=StreamingResponse)
async def get_sea_summary_file(
    tender_id: str,
    db=Depends(get_db),
):
    service = SummaryService(db)
    summary_file = await service.get_summary(UUID(tender_id))

    if not summary_file:
        workbook = openpyxl.Workbook()
        stream = io.BytesIO()
        workbook.save(stream)
        stream.seek(0)

        empty_filename = "empty_summary.xlsx"
        encoded_filename = quote(empty_filename)
        headers = {
            "Content-Disposition": f"attachment; filename*=UTF-8''{encoded_filename}",
            "Content-Type": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
        }

        return StreamingResponse(
            content=stream,
            headers=headers,
            media_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
        )

    else:
        encoded_filename = quote(summary_file.name)
        headers = {
            "Content-Disposition": f"attachment; filename*=UTF-8''{encoded_filename}",
            "Content-Type": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
        }

        file_path = pathlib.Path(summary_file.file_path)

        def iterfile():
            with open(file_path, mode="rb") as file_like:
                yield from file_like

        return StreamingResponse(
            content=iterfile(),
            headers=headers,
            media_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
        )


@router.post(path="/pipe", summary="【PP管件】汇总指定招标的投标文件。")
async def create_pipe_summary(
    tender_id: str,
    db=Depends(get_db),
):
    service = SummaryService(db)
    try:
        message = await service.create_summary_for_pipe_fitting(UUID(tender_id))
        return {"message": message}
    except Exception as e:
        print(f"!!!!!! API ROUTE CAUGHT EXCEPTION: {e}")
        raise HTTPException(status_code=400, detail="汇总失败" + str(e))


@router.get(
    path="/pipe",
    response_class=StreamingResponse,
    summary="【PP管件】获取指定招标的汇总Excel文件。",
)
async def get_pipe_summary_file(
    tender_id: str,
    db=Depends(get_db),
):
    service = SummaryService(db)
    summary_file = await service.get_summary_for_pipe_fitting(UUID(tender_id))

    if not summary_file:
        # 没有汇总文件，返回空Excel，文件名与预期一致
        tender = await service.tender_crud.get_by_id(UUID(tender_id))
        file_name = f"{tender.quarter}{tender.category}汇总文件.xlsx"
        workbook = openpyxl.Workbook()
        stream = io.BytesIO()
        workbook.save(stream)
        stream.seek(0)
        return StreamingResponse(
            stream,
            media_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
            headers={
                "Content-Disposition": f"attachment; filename*=utf-8''{file_name}"
            },
        )
    else:
        file_path = summary_file.file_path
        file_name = summary_file.name
        encoded_file_name = quote(file_name)

        def file_iterator():
            with open(file_path, "rb") as f:
                while True:
                    chunk = f.read(8192)
                    if not chunk:
                        break
                    yield chunk

        return StreamingResponse(
            file_iterator(),
            media_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
            headers={
                "Content-Disposition": f"attachment; filename*=UTF-8''{encoded_file_name}"
            },
        )


@router.post(path="/electrical", summary="【电气】汇总指定招标的投标文件。")
async def create_electrical_summary(
    tender_id: str,
    db=Depends(get_db),
):
    service = SummaryService(db)
    try:
        message = await service.create_summary_for_electrical(UUID(tender_id))
        return {"message": message}
    except Exception as e:
        import traceback

        print(f"!!!!!! API ROUTE CAUGHT EXCEPTION: {e}")
        traceback.print_exc()
        raise HTTPException(status_code=400, detail="汇总失败" + str(e))

@router.get(
    path="/electrical",
    response_class=StreamingResponse,
    summary="【电气】获取指定招标的汇总Excel文件。",
)
async def get_electrical_summary_file(
    tender_id: str,
    db=Depends(get_db),
):
    service = SummaryService(db)
    summary_file = await service.get_summary_for_electrical(UUID(tender_id))

    if not summary_file:
        # 没有汇总文件，返回空Excel，文件名与预期一致
        tender = await service.tender_crud.get_by_id(UUID(tender_id))
        file_name = f"{tender.quarter}{tender.category}汇总文件.xlsx"
        workbook = openpyxl.Workbook()
        stream = io.BytesIO()
        workbook.save(stream)
        stream.seek(0)
        return StreamingResponse(
            stream,
            media_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
            headers={
                "Content-Disposition": f"attachment; filename*=utf-8''{file_name}"
            },
        )
    else:
        file_path = summary_file.file_path
        file_name = summary_file.name
        encoded_file_name = quote(file_name)

        def file_iterator():
            with open(file_path, "rb") as f:
                while True:
                    chunk = f.read(8192)
                    if not chunk:
                        break
                    yield chunk

        return StreamingResponse(
            file_iterator(),
            media_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
            headers={
                "Content-Disposition": f"attachment; filename*=UTF-8''{encoded_file_name}"
            },
        )

@router.post(path="/steel", summary="【钢材】汇总指定招标的投标文件。")
async def create_steel_summary(
    tender_id: str,
    db=Depends(get_db),
):
    service = SummaryService(db)
    try:
        message = await service.create_summary_for_steel(UUID(tender_id))
        return {"message": message}
    except Exception as e:
        raise HTTPException(status_code=400, detail="汇总失败" + str(e))

@router.get(
    path="/steel",
    response_class=StreamingResponse,
    summary="【钢材】获取指定招标的汇总Excel文件。",
)
async def get_steel_summary_file(
    tender_id: str,
    db=Depends(get_db),
):
    service = SummaryService(db)
    summary_file = await service.get_summary_for_steel(UUID(tender_id))

    if not summary_file:
        # 没有汇总文件，返回空Excel，文件名与预期一致
        tender = await service.tender_crud.get_by_id(UUID(tender_id))
        file_name = f"{tender.quarter}{tender.category}汇总文件.xlsx"
        workbook = openpyxl.Workbook()
        stream = io.BytesIO()
        workbook.save(stream)
        stream.seek(0)
        return StreamingResponse(
            stream,
            media_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
            headers={
                "Content-Disposition": f"attachment; filename*=utf-8''{file_name}"
            },
        )
    else:
        file_path = summary_file.file_path
        file_name = summary_file.name
        encoded_file_name = quote(file_name)

        def file_iterator():
            with open(file_path, "rb") as f:
                while True:
                    chunk = f.read(8192)
                    if not chunk:
                        break
                    yield chunk

        return StreamingResponse(
            file_iterator(),
            media_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
            headers={
                "Content-Disposition": f"attachment; filename*=UTF-8''{encoded_file_name}"
            },
        )
